package com.clarence.dada.modular.system.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.redis.RedisOperatorApi;
import com.clarence.dada.modular.system.user.entity.SysUserRoleEntity;
import com.clarence.dada.modular.system.user.entity.req.SysUserReq;
import com.clarence.dada.modular.system.user.entity.req.UserRoleReq;
import com.clarence.dada.modular.system.user.mapper.SysUserRoleMapper;
import com.clarence.dada.modular.system.user.service.SysUserRoleService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统用户角色service接口实现类
 *
 * @author luojie
 * @date 2020/11/6 10:28
 */
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRoleEntity> implements SysUserRoleService {

    @Resource(name = "userRoleCacheApi")
    private RedisOperatorApi<List<Long>> userRoleCacheApi;

    @Override
    public void add(UserRoleReq req) {
        SysUserRoleEntity sysUserRole = new SysUserRoleEntity();
        BeanUtil.copyProperties(req, sysUserRole);
        this.save(sysUserRole);
    }

    @Override
    public void del(UserRoleReq req) {
        SysUserRoleEntity sysUserRole = querySysUserRoleById(req);
        this.removeById(sysUserRole.getUserRoleId());
    }

    @Override
    public void delByUserId(Long userId) {
        LambdaQueryWrapper<SysUserRoleEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRoleEntity::getUserId, userId);
        this.remove(queryWrapper);
    }

    @Override
    public void edit(UserRoleReq req) {
        SysUserRoleEntity sysUserRole = this.querySysUserRoleById(req);
        BeanUtil.copyProperties(req, sysUserRole);
        this.updateById(sysUserRole);
    }

    @Override
    public SysUserRoleEntity detail(UserRoleReq req) {
        LambdaQueryWrapper<SysUserRoleEntity> queryWrapper = this.createQueryWrapper(req);
        return this.getOne(queryWrapper, false);
    }

    @Override
    public List<SysUserRoleEntity> findList(UserRoleReq req) {
        LambdaQueryWrapper<SysUserRoleEntity> queryWrapper = this.createQueryWrapper(req);
        return this.list(queryWrapper);
    }

    @Override
    public List<SysUserRoleEntity> findListByUserId(Long userId) {
        UserRoleReq req = new UserRoleReq();
        req.setUserId(userId);
        return this.findList(req);
    }

    @Override
    public List<Long> findRoleIdsByUserId(Long userId) {

        // 先从缓存获取用户绑定的角色
        String key = String.valueOf(userId);
        List<Long> userRolesCache = userRoleCacheApi.get(key);
        if (userRolesCache != null) {
            return userRolesCache;
        }

        // 从数据库查询角色
        UserRoleReq req = new UserRoleReq();
        req.setUserId(userId);
        List<SysUserRoleEntity> sysUserRoleList = this.findList(req);
        List<Long> userRoles = sysUserRoleList.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
        userRoleCacheApi.put(key, userRoles);
        return userRoles;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignRoles(SysUserReq req) {
        // 获取用户id
        Long userId = req.getUserId();

        // 删除已有角色
        this.delByUserId(userId);

        // 为该用户授权角色
        List<Long> rileIds = req.getGrantRoleIdList();

        // 批量添加角色
        List<SysUserRoleEntity> sysUserRoleList = CollUtil.newArrayList();
        rileIds.forEach(roleId -> {
            SysUserRoleEntity sysUserRole = new SysUserRoleEntity();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            sysUserRoleList.add(sysUserRole);
        });

        this.saveBatch(sysUserRoleList);

        // 清除用户角色的缓存
        userRoleCacheApi.remove(String.valueOf(userId));
    }

    /**
     * 根据主键查询
     *
     * @param req dto实体
     * @author chenjinlong
     * @date 2021/2/3 15:02
     */
    private SysUserRoleEntity querySysUserRoleById(UserRoleReq req) {
        return this.getById(req.getUserRoleId());
    }

    /**
     * 构建 QueryWrapper
     *
     * @param req dto实体
     * @author chenjinlong
     * @date 2021/2/3 14:54
     */
    private LambdaQueryWrapper<SysUserRoleEntity> createQueryWrapper(UserRoleReq req) {
        LambdaQueryWrapper<SysUserRoleEntity> queryWrapper = new LambdaQueryWrapper<>();
        // SQL拼接
        queryWrapper.eq(ObjectUtil.isNotNull(req.getUserRoleId()), SysUserRoleEntity::getUserRoleId, req.getUserRoleId());
        queryWrapper.eq(ObjectUtil.isNotNull(req.getUserId()), SysUserRoleEntity::getUserId, req.getUserId());
        queryWrapper.eq(ObjectUtil.isNotNull(req.getRoleId()), SysUserRoleEntity::getRoleId, req.getRoleId());

        return queryWrapper;
    }

}
